package com.keboom.show.service.impl;

import com.keboom.show.common.util.JwtTokenUtil;
import com.keboom.show.mapper.SpManagerMapper;
import com.keboom.show.mapper.SpRoleMapper;
import com.keboom.show.model.SpManager;
import com.keboom.show.model.SpManagerExample;
import com.keboom.show.model.SpRole;
import com.keboom.show.model.SpUser;
import com.keboom.show.service.ManagerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;


/**
 * Created by keboom on 2020/9/7.
 */
@Service
public class ManagerServiceImpl implements ManagerService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ManagerServiceImpl.class);
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private SpManagerMapper managerMapper;
    @Autowired
    private SpRoleMapper roleMapper;


    /**
     *
     * @param username 用户名
     * @param password 密码
     * @return
     */
    @Override
    public String login(String username, String password) {
        String token = null;
        try {
            // 在SecurityConfig.java中已经重写userDetailsService方法，此方法通过查询数据库，来填充UserDetails，而UserDetails中包含用户名，密码，权限列表。
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            // 传过来的password，和从数据库查出来的userDetails.getPassword()，进行比较
            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
                throw new BadCredentialsException("密码不正确");
            }
            // 这是用来设置该用户的权限吧？？
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            // 如果登录成功则生成token并返回
            token = jwtTokenUtil.generateToken(userDetails);
        } catch (AuthenticationException e) {
            LOGGER.warn("登录异常:{}", e.getMessage());
        }
        return token;
    }

    @Override
    public SpManager getManagerByUsername(String username) {
        SpManagerExample example = new SpManagerExample();
        example.createCriteria().andMgNameEqualTo(username);
        List<SpManager> managers = managerMapper.selectByExample(example);
        if (managers != null && managers.size() > 0){
            SpManager manager = managers.get(0);
            return manager;
        }
        return null;
    }

    /**
     * 该项目前端没有注册功能，我自己写了一个注册接口用来测试
     * @param manager
     * @return
     */
    @Override
    public SpManager register(SpManager manager) {
        SpManager spmanager = new SpManager();
        BeanUtils.copyProperties(manager, spmanager);
        spmanager.setMgTime((int) System.currentTimeMillis());
        spmanager.setMgState(0);
        SpManagerExample example = new SpManagerExample();
        example.createCriteria().andMgNameEqualTo(spmanager.getMgName());
        List<SpManager> managers = managerMapper.selectByExample(example);
        if (managers.size() > 0){
            return null;
        }
        String encode = passwordEncoder.encode(spmanager.getMgPwd());
        spmanager.setMgPwd(encode);
        managerMapper.insert(spmanager);
        return spmanager;
    }

    /**
     * 这个方法本应该获取权限列表的
     * @param username
     * @return
     */
    @Override
    public String getManagerRoles(String username) {
        SpManager manager = getManagerByUsername(username);
        Integer roleId = manager.getRoleId();
        SpRole spRole = roleMapper.selectByPrimaryKey(roleId);
        return spRole.getPsIds();
    }
}
